package validation.jexp;

import com.jgoodies.binding.PresentationModel;
import com.jgoodies.binding.adapter.BasicComponentFactory;
import com.jgoodies.binding.beans.Model;
import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.factories.ButtonBarFactory;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.event.ActionEvent;

/**
 * Demonstrates three different styles when to commit changes:
 * on key typed, on focus lost, on OK/Apply pressed.
 * Therefore we bind 3 JTextFields to 3 String typed ValueModels
 * that honor the commit style. And we bind 3 JLabels directly
 * to these ValueModels that display the current value.<p>
 *
 * The ValueModels used in this example are requested from a
 * PresentationModel that adapts text properties of a TextBean.
 * This is just to demonstrate a consistent binding style.
 * The same techniques work with any ValueModel.
 *
 * @author Karsten Lentzsch
 * @version $Revision: 1.4 $
 *
 * @see com.jgoodies.binding.PresentationModel
 */
public class CommitStylesExample {
    /**
     * Holds a TextBean and vends ValueModels that adapt TextBean properties.
     * As an alternative to this PresentationModel we could use 3 ValueModels,
     * for example 3 ValueHolders, or any other ValueModel implementation.
     */
    private final PresentationModel presentationModel;
    private JTextComponent onKeyTypedField;
    private JTextComponent onFocusLostField;
    private JTextComponent onApplyField;
    private JLabel onKeyTypedLabel;
    private JLabel onFocusLostLabel;
    private JLabel onApplyLabel;
    private JButton applyButton;


    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel("com.jgoodies.looks.plastic.PlasticXPLookAndFeel");
        } catch (Exception ex) {}

        String title = "Binding Tutorial:Commit Styles";
        CommitStylesExample example = new CommitStylesExample();
        JComponent panel = example.build();
        JGoodiesValidationUtils.showFrame(title, panel);
    }

    public CommitStylesExample() {
        this.presentationModel = new PresentationModel(new TextBean());
    }

    private void initComponents() {
        onKeyTypedField = BasicComponentFactory.createTextField(presentationModel.getModel(TextBean.PROPERTYNAME_TEXT1), false);
        onKeyTypedLabel = BasicComponentFactory.createLabel(presentationModel.getModel(TextBean.PROPERTYNAME_TEXT1));
        onFocusLostField = BasicComponentFactory.createTextField(presentationModel.getModel(TextBean.PROPERTYNAME_TEXT2));
        onFocusLostLabel = BasicComponentFactory.createLabel(presentationModel.getModel(TextBean.PROPERTYNAME_TEXT2));
        onApplyField = BasicComponentFactory.createTextField(presentationModel.getBufferedModel(TextBean.PROPERTYNAME_TEXT3));
        onApplyLabel = BasicComponentFactory.createLabel(presentationModel.getModel(TextBean.PROPERTYNAME_TEXT3));
        applyButton = new JButton(new ApplyAction());
    }

    public JComponent build() {
        initComponents();

        FormLayout layout = new FormLayout("right:max(50dlu;pref), 3dlu, 50dlu, 9dlu, 50dlu",
                "p, 6dlu, p, 3dlu, p, 3dlu, p, 17dlu, p");
        PanelBuilder builder = new PanelBuilder(layout);
        builder.setDefaultDialogBorder();
        CellConstraints cc = new CellConstraints();
        builder.addTitle("Commit Style", cc.xy(1, 1));
        builder.addTitle("Value", cc.xy(5, 1));
        builder.addLabel("Key Typed", cc.xy(1, 3));
        builder.add(onKeyTypedField, cc.xy(3, 3));
        builder.add(onKeyTypedLabel, cc.xy(5, 3));
        builder.addLabel("Focus Lost", cc.xy(1, 5));
        builder.add(onFocusLostField, cc.xy(3, 5));
        builder.add(onFocusLostLabel, cc.xy(5, 5));
        builder.addLabel("Apply Pressed", cc.xy(1, 7));
        builder.add(onApplyField, cc.xy(3, 7));
        builder.add(onApplyLabel, cc.xy(5, 7));
        builder.add(buildButtonBar(), cc.xyw(1, 9, 5));
        return builder.getPanel();
    }

    private JComponent buildButtonBar() {
        return ButtonBarFactory.buildRightAlignedBar(applyButton);
    }

    private final class ApplyAction extends AbstractAction {
        private ApplyAction() {
            super("Apply");
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            presentationModel.triggerCommit();
        }
    }

    public static class TextBean extends Model {
        public static final String PROPERTYNAME_TEXT1 = "text1";
        public static final String PROPERTYNAME_TEXT2 = "text2";
        public static final String PROPERTYNAME_TEXT3 = "text3";

        private String text1;
        private String text2;
        private String text3;

        public TextBean() {
            this.text1 = "Text1";
            this.text2 = "Text2";
            this.text3 = "Text3";
        }

        public String getText1() {
            return text1;
        }

        public void setText1(String text1) {
            String oldText = this.text1;
            this.text1 = text1;
            firePropertyChange(PROPERTYNAME_TEXT1, oldText, text1);
        }

        public String getText2() {
            return text2;
        }

        public void setText2(String text2) {
            String oldText = this.text2;
            this.text2 = text2;
            firePropertyChange(PROPERTYNAME_TEXT2, oldText, text2);
        }

        public String getText3() {
            return text3;
        }

        public void setText3(String text3) {
            String oldText = this.text3;
            this.text3 = text3;
            firePropertyChange(PROPERTYNAME_TEXT3, oldText, text3);
        }
    }
}
